#pragma once

/**
 * @file tcp_server.h
 * @brief TCP服务器实现
 * @details 提供TCP服务器功能，包括监听连接、数据收发和连接管理
 */

#include "tcp_socket.h"

namespace Common {
  /**
   * @struct TCPServer
   * @brief TCP服务器类
   * @details 实现基于epoll的TCP服务器，管理多个客户端连接和数据交互
   */
  struct TCPServer {
    /**
     * @brief 构造函数
     * @param logger 日志对象引用，用于记录服务器操作
     */
    explicit TCPServer(Logger &logger)
        : listener_socket_(logger), logger_(logger) {
    }

    /**
     * @brief 开始在指定接口和端口上监听连接
     * @param iface 网络接口
     * @param port 端口号
     */
    auto listen(const std::string &iface, int port) -> void;

    /**
     * @brief 检查新连接或已断开的连接，并更新跟踪套接字的容器
     * @details 使用epoll检查套接字事件，处理新连接、可读、可写和错误事件
     */
    auto poll() noexcept -> void;

    /**
     * @brief 发送和接收数据
     * @details 从发送缓冲区发送数据，并从接收缓冲区读取传入的数据
     */
    auto sendAndRecv() noexcept -> void;

  private:
    /**
     * @brief 将套接字文件描述符添加到EPOLL列表中
     * @param socket 要添加的套接字指针
     * @return 成功返回true，失败返回false
     */
    auto addToEpollList(TCPSocket *socket);

  public:
    /**
     * @brief epoll文件描述符
     * @details 用于监听多个套接字事件的epoll实例
     */
    int epoll_fd_ = -1;
    /**
     * @brief 监听套接字
     * @details 服务器用于监听新连接的套接字
     */
    TCPSocket listener_socket_;

    /**
     * @brief epoll事件数组
     * @details 用于存储epoll_wait返回的事件，最多支持1024个事件
     */
    epoll_event events_[1024];

    /**
     * @brief 套接字集合
     * @details 存储所有用于接收和发送数据的套接字
     */
    std::vector<TCPSocket *> receive_sockets_, send_sockets_;

    /**
     * @brief 数据可用时的回调函数
     * @details 当有新数据可用时调用的函数
     */
    std::function<void(TCPSocket *s, Nanos rx_time)> recv_callback_ = nullptr;
    /**
     * @brief 数据接收完成回调函数
     * @details 当所有TCP套接字的数据都已读取并分发完毕时调用的函数
     */
    std::function<void()> recv_finished_callback_ = nullptr;

    /**
     * @brief 时间字符串缓存
     * @details 用于日志记录的时间字符串缓存
     */
    std::string time_str_;
    
    /**
     * @brief 日志对象引用
     * @details 用于记录服务器操作的日志信息
     */
    Logger &logger_;
  };
}
